/**
  @Author: 王炜皓
  @Date: 2023-06-09 14:36:45
  @LastEditTime: 2023-07-14 17:34:31
  @LastEditors: 王炜皓
  @Description: 克里金热力图实现类
  @FilePath: \Integration-of-heaven-and-earth-vue\src\assets\utumSDK\extend\heatMap\kriging.js
 **/
  import * as kriging from "./krigingOriginCode.js";
  import * as turf from "@turf/turf";
  import { Intensity, Canvas } from "./Intensity";
  const Cesium = window.Cesium;
  class KrigingHeatmapIntensity {
    constructor(option = {},viewer) {
      this._min = option.min || 0; //最小值
      this._max = option.max || 100; //最大值
      this._size = option.size || 20; //光圈大小，像素值
      this._result = undefined; //热力图结果
      this._canvas = undefined; //离屏canvas
      this._viewer=viewer
      this._color= option.colors|| [
        "#FF0000", // 红色
        "#FF3F00", // 过渡颜色 1
        "#FF7F00", // 橙色
        "#FFBF00", // 过渡颜色 2
        "#FFFF00", // 黄色
        "#BFFF00", // 过渡颜色 3
        "#00FF00", // 绿色
        "#00FF7F", // 过渡颜色 4
        "#00FFFF", // 青色
        "#007FFF", // 过渡颜色 5
        "#0000FF", // 蓝色
        "#3F00FF", // 过渡颜色 6
        "#7F00FF", // 靛蓝色
        "#BF00FF", // 过渡颜色 7
        "#FF00FF", // 紫色
      ];
    }
  
  
    get min() {
      return this._min;
    }
    set min(val) {
      this._min = val;
      this.updateHeatmap(this._result.canvasData);
    }
    get max() {
      return this._max;
    }
    set max(val) {
      this._max = val;
      this.updateHeatmap(this._result.canvasData);
    }
    get size() {
      return this._size;
    }
    set size(val) {
      this._size = val;
      this.updateHeatmap(this._result.canvasData);
    }
    get color(){
      return  this._color
    }
    set color(val){
      this._color=val
    }
    get result() {
      return this._result;
    }
    /**
     * 创建热力图对象
     * @param {*} box 范围对象，经纬度值-{west,south,east,north}
     * @param {*} data 待绘制热力图的数据-[{x1,y1,value1},{x2,y2,value2},...]
     * @returns 热力图结果对象
     */
    init(option = {}) {
      this._min = option.min || 0; //最小值
      this._max = option.max || 100; //最大值
      this._size = option.size || 20; //光圈大小，像素值
    }
    create( data,polygon) {
      this.init()
      // this._viewer = viewer;
      let box = this.computeBox(data);
      console.log(data, "导入成功");
  
      const mercator_WestSouth = this.WGS84ToWebMercator(box.west, box.south, 0); //左下位置（墨卡托）
      const mercator_EastNorth = this.WGS84ToWebMercator(box.east, box.north, 0); //右上位置（墨卡托）
      const diffDegrees_X = mercator_EastNorth.x - mercator_WestSouth.x;
      const diffDegrees_Y = mercator_EastNorth.y - mercator_WestSouth.y;
      const diffMax = Math.max(diffDegrees_X, diffDegrees_Y);
      let multiple = diffMax / 300; //适当扩大倍数，以便绘制canvas
      const width = Math.ceil(diffDegrees_X / multiple);
      const height = Math.ceil(diffDegrees_Y / multiple);
      this.mercator_WestSouth = mercator_WestSouth;
      this.mercator_EastNorth = mercator_EastNorth;
      this.diffDegrees_X = diffDegrees_X;
      this.diffDegrees_Y = diffDegrees_Y;
      let canvasData = [];
      data.forEach((element) => {
        const curMercator = this.WGS84ToWebMercator(
          Number(element.x),
          Number(element.y),
          0
        );
        //归一化
        const per_X = (curMercator.x - mercator_WestSouth.x) / diffDegrees_X;
        const currentPix_X = Math.ceil(per_X * width);
        const per_Y = (curMercator.y - mercator_WestSouth.y) / diffDegrees_Y;
        const currentPix_Y = Math.ceil(per_Y * height);
        const currentValue = Number(element.value);
        canvasData.push({
          x: currentPix_X,
          y: height - currentPix_Y - 1,
          value: currentValue,
        });
        let cordDtata = [];
        cordDtata.push([currentPix_X]);
      });
      let canvas = new Canvas(width, height);
      let context = canvas.getContext("2d");
      context.clearRect(0, 0, canvas.width, canvas.height);
      canvas.style.display = "block";
      canvas.getContext("2d").globalAlpha = 0.75; //设置透明度
      let values = data.map((point) => point.value);
      let x_values = data.map((point) => point.x);
      let y_values = data.map((point) => point.y);
      let variogram = kriging.default.train(
        values,
        x_values,
        y_values,
        "exponential",
        0,
        100
      );
      let cood = [];
      cood.push();
      let grid = kriging.default.grid(
        [
          [
            [box.west, box.south],
            [box.west, box.north],
            [box.east, box.north],
            [box.east, box.south],
            [box.west, box.south],
          ],
        ],
        variogram,
        (box.east - box.west) / 1000
      );
      let colors =this._color
  
      kriging.default.plot(
        canvas,
        grid,
        [box.west, box.east],
        [box.south, box.north],
        colors
      );
      var positions = polygon.map(function(point) {
        return Cesium.Cartesian3.fromElements(point.x, point.y, point.z);
    });
      let entity = this._viewer.entities.add({
        polygon: {
          hierarchy: {
            positions:positions
          },
          material: new Cesium.ImageMaterialProperty({
            image: canvas, //使用贴图的方式将结果贴到面上
          }),
        },
      });
   
      this._canvas = canvas;
      this._result = { box, data, canvasData, entity };
      return this._result;
    }
    /**
     * 更新热力图数据
     * @param {*} data 待绘制热力图的数据-[{x1,y1,value1},{x2,y2,value2},...]
     */
    setData(data) {
      if (!this._result) {
        return;
      }
    
      let canvasData = [];
      const height = this._canvas.height;
      const width = this._canvas.width;
      data.forEach((element) => {
        const curMercator = this.WGS84ToWebMercator(
          Number(element.x),
          Number(element.y),
          0
        );
  
      });
      this._result.data = data;
      this._result.canvasData = data;
      this.updateHeatmap(data);
    }
    /**
     * 更新热力图
     * @param {*} data 参考canvasData
     * @returns 热力图结果对象
     */
    updateHeatmap(data) {
      console.log(this._result.entity,'this._result.entity');
      let canvas = this._canvas;
      let context = canvas.getContext("2d");
      let box = this.computeBox(data);
  
      context.clearRect(0, 0, canvas.width, canvas.height);
      let values = data.map((point) => point.value);
      let x_values = data.map((point) => point.x);
      let y_values = data.map((point) => point.y);
      let variogram = kriging.default.train(
        values,
        x_values,
        y_values,
        "exponential",
        0,
        100
      );
      let cood = [];
      cood.push();
      let grid = kriging.default.grid(
        [
          [
            [box.west, box.south],
            [box.west, box.north],
            [box.east, box.north],
            [box.east, box.south],
            [box.west, box.south],
          ],
        ],
        variogram,
        (box.east - box.west) / 556
      );
      let colors =this._color
      kriging.default.plot(
        canvas,
        grid,
        [box.west, box.east],
        [box.south, box.north],
        colors
      );
      // this._result.entity=undefined
      // this._result.entity.material = new Cesium.ImageMaterialProperty({
      //   image: canvas,
      // });
      this._result && this._viewer.entities.remove(this._result.entity);
      this._result.entity.material = new Cesium.ImageMaterialProperty({
        image: canvas,
        transparent: true,
      });
      // this._viewer.entities.remove(this._result.entity)
      // this._result.entity=null
      this._result.entity = this._viewer.entities.add({
        polygon: {
          hierarchy: {
            positions: Cesium.Cartesian3.fromDegreesArray([
              box.west,
              box.south,
              box.west,
              box.north,
              box.east,
              box.north,
              box.east,
              box.south,
              box.west,
              box.south,
            ]),
          },
          material: new Cesium.ImageMaterialProperty({
            image: canvas, //使用贴图的方式将结果贴到面上
          }),
        },
      });
      // this._result = { box, data, canvasData, entity };
      return this._result;
    }
  
    computeBox(data) {
      const points = data.map((item) => turf.point([item.x, item.y], item));
      const featureCollection = turf.featureCollection(points);
      const enveloped = turf.bbox(featureCollection);
      const result = {
        west: enveloped[0],
        south: enveloped[1],
        east: enveloped[2],
        north: enveloped[3],
      };
      return result;
      console.log(result);
    }
  
    WGS84ToWebMercator(lng, lat, height) {
      let mercator = {};
      let x = (lng * 20037508.34) / 180;
      let y = Math.log(Math.tan(((90 + lat) * Math.PI) / 360)) / (Math.PI / 180);
      y = (y * 20037508.34) / 180;
      mercator.x = x;
      mercator.y = y;
      mercator.z = height;
      return mercator;
    }
    clearAll() {
      this._result && this._viewer.entities.remove(this._result.entity);
      this._result = undefined;
    }
  }
  export default KrigingHeatmapIntensity;
  